using System.Collections.Generic;
using System.Text;
using System.Web;

using octalforty.Waffle.ComponentModel.Navigation;

using octalforty.Waffle.ObjectModel.Business.Objects;

namespace octalforty.Waffle.ComponentModel.Navigation.Impl
{
    /// <summary>
    /// URL Rewriting-aware implementation of the <see cref="INavigationService"/>.
    /// </summary>
    public class UrlRewritingNavigationService : INavigationService
    {
        #region Private Member Variables
        private IHttpRequestProvider httpRequestProvider;
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets a reference to the <see cref="IHttpRequestProvider"/>.
        /// </summary>
        public IHttpRequestProvider HttpRequestProvider
        {
            get { return httpRequestProvider; }
            set { httpRequestProvider = value; }
        }
        #endregion

        /// <summary>
        /// Initializes a new instance of <see cref="UrlRewritingNavigationService"/> class.
        /// </summary>
        public UrlRewritingNavigationService()
        {
        }

        #region INavigationService Members
        /// <summary>
        /// Resolves a <paramref name="virtualUrl"/> to a fully-qualified URL.
        /// </summary>
        /// <param name="virtualUrl"></param>
        /// <returns></returns>
        public string ResolveVirtualUrl(string virtualUrl)
        {
            if(virtualUrl.StartsWith("~/"))
            {
                return CombineUris(
                        CombineUris(string.Format("{0}://{1}", HttpRequestProvider.HttpRequest.Url.Scheme,
                            HttpRequestProvider.HttpRequest.Url.Authority), HttpRequestProvider.HttpRequest.ApplicationPath),
                        virtualUrl.Substring(2));
            } // if

            return virtualUrl;
        }

        /// <summary>
        /// Returns a virtual URL to the Forum view page for <paramref name="forum"/>.
        /// </summary>
        /// <param name="forum"></param>
        /// <returns></returns>
        public string GetForumUrl(Forum forum)
        {
            return FormatVirtualUrl("~/forums/{0}/", forum.ID);
        }

        /// <summary>
        /// Returns a virtual URL to the New Discussion page for <paramref name="forum"/>.
        /// </summary>
        /// <param name="forum"></param>
        /// <returns></returns>
        public string GetNewDiscussionUrl(Forum forum)
        {
            return FormatVirtualUrl("~/forums/{0}/discussions/new/", forum.ID);
        }

        /// <summary>
        /// Returns a virtual URL to the Discussion view page for <paramref name="discussion"/>.
        /// </summary>
        /// <param name="discussion"></param>
        /// <returns></returns>
        public string GetDiscussionUrl(Discussion discussion)
        {
            return FormatVirtualUrl("~/forums/{0}/discussions/{1}/", discussion.Forum.ID, discussion.ID);
        }
        #endregion

        public static string FormatVirtualUrl(string formatString, params object[] args)
        {
            List<string> encodedArgs =
                new List<object>(args).ConvertAll<string>(delegate(object value)
                    { return HttpUtility.UrlEncode(value.ToString(), Encoding.UTF8); });

            return string.Format(formatString, encodedArgs.ToArray());
        }

        public static string CombineUris(string baseUri, string uri)
        {
            if(baseUri.EndsWith("/") && uri.StartsWith("/"))
                return baseUri + uri.Substring(1);

            if(baseUri.EndsWith("/") || uri.StartsWith("/"))
                return baseUri + uri;

            return baseUri + "/" + uri;
        }
    }
}
